﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace MapLibrary
{
    class EditorNode : ITransformable
    {
        private Color HOVERCOLOR = Color.Red;
        private Color NORMALCOLOR = Color.Blue;

        /**
         * The MapNode that the EditorNode is wrapping.  When changes are made
         * to the editor node, changes will be made to the underlying MapNode.
         */
        private MapNode mNodeToEdit;

        /**
         * This texture is for the rectangle surrounding the MapNode when there is no mouse hover
         * over it.
         */
        private Texture2D mRectangleTexture;

        /**
         * This texture is for the rectangle surrounding the MapNode when there is mouse hover
         * over it.
         */
        private Texture2D mHoverRectangleTexture;

        /**
         * Flag that indicates whether or not the node is being hovered over
         * by the mouse.
         */
        private bool isHovered;

        private bool mDrawBoundingBox;

        public EditorNode(MapNode Node)
        {
            mNodeToEdit = Node;
            isHovered = false;
            mDrawBoundingBox = true;
        }

        /**
         * Draws the MapNode and all editor elements.
         */
        public void Draw(SpriteBatch Batch, WorldViewport Viewport)
        {
            mNodeToEdit.Draw(Batch, Viewport);

            if(mDrawBoundingBox)
                DrawNodeRectangle(Batch, Viewport);
        }

        /**
         * Modify the hover property.
         */
        public bool Hover
        {
            get { return isHovered; }
            set { isHovered = value; }
        }

        public bool DrawBoundingBox
        {
            get { return mDrawBoundingBox; }
            set { mDrawBoundingBox = value; }
        }

        public int Alpha
        {
            get { return mNodeToEdit.Alpha; }
            set { mNodeToEdit.Alpha = value; }
        }

        public float Rotation
        {
            get { return mNodeToEdit.Rotation; }
            set
            {
                mNodeToEdit.Rotation = value;
            }
        }

        public Vector2 Scale
        {
            get { return mNodeToEdit.Scale; }
            set { mNodeToEdit.Scale = value; }
        }

        public Vector2 Position
        {
            get { return mNodeToEdit.Position; }
            set
            {
                mNodeToEdit.Position = value; 
            }
        }

        public Vector2 Center
        {
            get { return mNodeToEdit.Center; }
        }

        /**
         * Creates the rectangle that will hang around the MapNode that is contained
         * in this EditorNode.  Also loads all necessary textures for the node.
         */
        public void Load(GraphicsDevice Graphics, ContentManager Manager)
        {
            mRectangleTexture = new Texture2D(Graphics, mNodeToEdit.Width, mNodeToEdit.Height);

            Color[] data = new Color[mNodeToEdit.Width * mNodeToEdit.Height];
            Color transparency = new Color(0, 0, 0, 0);

            for (int i = 0; i < mNodeToEdit.Width * mNodeToEdit.Height; i++)
            {
                data[i] = transparency;
            }

            for (int i = 0; i < mNodeToEdit.Width; i++)
            {
                data[i] = NORMALCOLOR;
            }

            for (int i = 0; i < mNodeToEdit.Height; i++)
            {
                data[i * mNodeToEdit.Width] = NORMALCOLOR;
                data[i * mNodeToEdit.Width + mNodeToEdit.Width - 1] = NORMALCOLOR;
            }

            for (int i = 0; i < mNodeToEdit.Width; i++)
            {
                data[(mNodeToEdit.Height - 1) * (mNodeToEdit.Width) + i] = NORMALCOLOR;
            }

            mRectangleTexture.SetData(data);

            mHoverRectangleTexture = new Texture2D(Graphics, mNodeToEdit.Width, mNodeToEdit.Height);

            data = new Color[mNodeToEdit.Width * mNodeToEdit.Height];
            transparency = new Color(0, 0, 0, 0);

            for (int i = 0; i < mNodeToEdit.Width * mNodeToEdit.Height; i++)
            {
                data[i] = transparency;
            }

            for (int i = 0; i < mNodeToEdit.Width; i++)
            {
                data[i] = HOVERCOLOR;
            }

            for (int i = 0; i < mNodeToEdit.Height; i++)
            {
                data[i * mNodeToEdit.Width] = HOVERCOLOR;
                data[i * mNodeToEdit.Width + mNodeToEdit.Width - 1] = HOVERCOLOR;
            }

            for (int i = 0; i < mNodeToEdit.Width; i++)
            {
                data[(mNodeToEdit.Height - 1) * (mNodeToEdit.Width) + i] = HOVERCOLOR;
            }

            mHoverRectangleTexture.SetData(data);
        }

        /**
         * Draws all editor elements around the MapNode.
         */
        private void DrawNodeRectangle(SpriteBatch Batch, WorldViewport Viewport)
        {
            Rectangle RectangleTextureRect = BuildNodeRectangle(Viewport);
            Texture2D TextureToUse;

            if (isHovered)
                TextureToUse = mHoverRectangleTexture;
            else
                TextureToUse = mRectangleTexture;

            Batch.Draw(
                TextureToUse,
                RectangleTextureRect,
                null,
                Color.White,
                mNodeToEdit.Rotation,
                mNodeToEdit.Center,
                SpriteEffects.None,
                0f);
        }

        /**
         * Builds the Node Rectangle that handles where the rectangle around
         * the MapNode gets drawn.
         */
        public Rectangle BuildNodeRectangle(WorldViewport Viewport)
        {
            Rectangle NodeRectangle = new Rectangle();
            Vector2 ViewportCoords = Viewport.WorldToViewportCoords(mNodeToEdit.Position);
            NodeRectangle.X = (int)ViewportCoords.X;
            NodeRectangle.Y = (int)ViewportCoords.Y;
            NodeRectangle.Width = (int)(mNodeToEdit.Width * mNodeToEdit.Scale.X);
            NodeRectangle.Height = (int)(mNodeToEdit.Height * mNodeToEdit.Scale.Y);
            return NodeRectangle;
        }

        public void SetPosition(Vector2 Position)
        {
            this.Position = Position;
        }

        public Vector2 GetPosition()
        {
            return Position;
        }

        public void SetRotation(float rotation)
        {
            this.Rotation = rotation;
        }

        public float GetRotation()
        {
            return Rotation;
        }

        public void SetScale(Vector2 newScale)
        {
            this.Scale = newScale;
        }

        public Vector2 GetScale()
        {
            return Scale;
        }

        public bool IsActive()
        {
            return true;
        }

        public Vector2 GetCenter()
        {
            return Center;
        }
    }
}
